package com.iias.communication.server;

import com.iias.common.util.log.LogUtils;
import com.iias.communication.domain.ServerConfig;
import com.iias.communication.interfaces.ServerConnectionHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import org.slf4j.Logger;

public class CommunicationServer implements Runnable{

    private final static Logger log = LogUtils.getLogger();


    private ServerConfig serverConfig;

    private ServerConnectionHandler connectionHandler;

    public CommunicationServer(ServerConfig serverConfig,ServerConnectionHandler connectionHandler) {
        this.serverConfig = serverConfig;
        this.connectionHandler = connectionHandler;
//        init();

    }

    @Override
    public void run() {
        init();
        log.info("服务端启动");
    }

    private void init(){
        // 1 创建线两个事件循环组
        // 一个是用于处理服务器端接收客户端连接的
         NioEventLoopGroup pGroup = new NioEventLoopGroup();
        // 一个是进行网络通信的（网络读写的）
         NioEventLoopGroup cGroup = new NioEventLoopGroup();
        // 2 创建辅助工具类ServerBootstrap，用于服务器通道的一系列配置
         ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(pGroup,cGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, serverConfig.getSoBacklog())
                .option(ChannelOption.SO_SNDBUF,serverConfig.getSoSndBuf())
                .option(ChannelOption.SO_RCVBUF,serverConfig.getSoRcvBuf())
                .option(ChannelOption.SO_KEEPALIVE,serverConfig.getSoKeepalive())
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                     public void initChannel(SocketChannel ch){
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast("decoder",new ServerFilterDecoder())
                                .addLast("encoder", new ByteArrayEncoder())
                                .addLast(new TcpServerHandler(connectionHandler));
            }
        });
        log.info("服务端开启等待客户端连接 port: "+getPort()+" ... ...");
        Channel ch = null;
        try {
            ch = serverBootstrap.bind(serverConfig.getPort()).sync().channel();
            ch.closeFuture().sync();
        }catch(InterruptedException e) {
            e.printStackTrace();
        }finally{
            pGroup.shutdownGracefully();
            cGroup.shutdownGracefully();
        }
//        log.info("netty server init() ");
    }


    public Integer getPort(){
        return serverConfig.getPort();
    }


}
